iT邦幫忙

2024 iThome 鐵人賽

DAY 13
0

Day13 select 語句經歷了哪些

昨天簡單分享 MySQL 軟體架構,今天接著說 select 語句經過了什麼

select語句 經歷了哪些

Step1. 連接器:一個 sql 被執行,那一定是從 client 建立一個連線,連線的基底(當然看底是指多底,但通常指 L4 Transport Layer) ,從使用者的角度就是稱作 TCP Socket,不過每加資料庫會有自己把 socket 往上再實作,可能加一些欄位或者功能,可以參考例如 The MySQL protocol

Step2. 查詢快取:快取在軟體裡面真的是非常重要,像 CPU 也有 cache 架構,影響執行速度很多。對MySQL來說,一條語句進來,首先就會盡查詢快取去看,之前有沒有執行過。這個快取會以 kev-value 的方式存在記憶體,key是語句,value是查詢結果。如果命中快取,就直接返回結果。
聽起來滿厲害的,但其實沒這麼容易命中,因為只要表有被更新,表的快取就會被清掉,而且快取的資料有可能很大,但是又很容易被清掉,所以 MySQL 8.0 後就把這個功能刪掉了, select 語句就不會進到這個階段,MySQL8之前,想關掉查詢快取,可以通過 query_cache_type 設定為 DEMAND。

Step3. 解析SQL:解析SQL就像解析程式語言一樣(例如java),會有詞法分析(tokenize)語法分析(主要檢查有沒有符合語法,像是驗證資料),然後就會生成SQL語法樹(就是一個樹狀結構),或稱作AST,之所以需要 AST 這個資料結構,就是最後在做執行的時候很好查詢,而且可以提早在語法檢查階段,把錯誤擋掉不用到執行階段才發現錯誤(early fail)。

step4. 執行SQL:這個步驟可以分成3個步驟

    (1). prepare-預處理階段:主要檢查 sql 語句中表跟欄位存不存在,不存在就返回。
    (2). optimize-優化階段:sql會生成「查詢計畫」,然後會計算此計畫的「成本」
    像是 `select * from product where id = 1` 中, id 是 PK,所以就只有一種查詢計畫。
    如果今天查的資料沒有命中索引,執行了全表掃描,資料量大時程式效能就會很慘
    像是我們有一張表建立了 PK,以及二級索引(假設可能很常需要模糊比對name) 
    `select * from product where id >1 and name like 'i%'`
    這時候就會有 走 PK id 的執行計畫,以及走 二級索引 name 的執行計畫
    這時候就會比對計算好的「成本」,選成本低的計畫去執行
    看查詢計畫可以用 `explain` 這個關鍵字放在 sql 前執行就可以看到

    (3). execute-執行階段

執行階段會講到回表, 索引下推等等觀念,我們獨立一篇明天再說


上一篇
Day12 資料庫原理-執行一條 select語句背後1
下一篇
Day14 select 經歷了哪些-執行sql階段
系列文
我獨自升級之資料庫從入門到中階20
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言